/*
 * Copyright (C) 2019 Peng fei Pan <panpfpanpf@outlook.me>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package me.panpf.sketch.zoom.block;

import me.panpf.sketch.Configuration;
import me.panpf.sketch.Sketch;
import me.panpf.sketch.cache.recycle.SizeConfigStrategy;
import me.panpf.sketch.datasource.DataSource;
import me.panpf.sketch.decode.ImageDecodeUtils;
import me.panpf.sketch.decode.ImageOrientationCorrector;
import me.panpf.sketch.decode.ImageType;
import me.panpf.sketch.uri.GetDataSourceException;
import me.panpf.sketch.uri.UriModel;
import me.panpf.sketch.util.ExifInterface;
import me.panpf.sketch.util.Log;
import me.panpf.sketch.util.SketchUtils;
import me.panpf.sketch.zoom.PixmapBuild;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;

import java.io.IOException;
import java.io.InputStream;

/**
 * 图片碎片解码器，支持纠正图片方向
 */
@SuppressWarnings("WeakerAccess")
public class ImageRegionDecoder {

    private final int exifOrientation;
    private Point imageSize;
    private String imageUri;
    private ImageType imageType;
    private ImageSource regionDecoder;

    public ImageRegionDecoder(String imageUri, Point imageSize, ImageType imageType, int exifOrientation, ImageSource imageSource) {
        this.imageUri = imageUri;
        this.imageSize = imageSize;
        this.imageType = imageType;
        this.exifOrientation = exifOrientation;
        this.regionDecoder = imageSource;
    }

    public static ImageRegionDecoder build(Context context, final String imageUri,
                                           final boolean correctImageOrientationDisabled) throws IOException {
        UriModel uriModel = UriModel.match(context, imageUri);
        if (uriModel == null) {
            throw new IllegalArgumentException("Unknown scheme uri. " + imageUri);
        }

        DataSource dataSource;
        try {
            dataSource = uriModel.getDataSource(context, imageUri, null);
        } catch (GetDataSourceException ex) {
            throw new IllegalArgumentException("Can not be generated DataSource.  " + imageUri, ex);
        }

        // 读取图片尺寸和类型
        ImageSource.DecodingOptions boundOptions = new ImageSource.DecodingOptions();
//        boundOptions.inJustDecodeBounds = true;
        PixmapBuild pixelMap = ImageDecodeUtils.decodeBitmap(dataSource, boundOptions);
        Point imageSize = new Point(pixelMap.getPixelMap().getImageInfo().size.width, pixelMap.getPixelMap().getImageInfo().size.height);

        // 读取图片方向并根据方向改变尺寸
        Configuration configuration = Sketch.with(context).getConfiguration();
        ImageOrientationCorrector orientationCorrector = configuration.getOrientationCorrector();
        int exifOrientation = ExifInterface.ORIENTATION_UNDEFINED;
        if (!correctImageOrientationDisabled) {
            exifOrientation = orientationCorrector.readExifOrientation("image/jpg", dataSource);
        }
        orientationCorrector.rotateSize(imageSize, exifOrientation);

//        InputStream inputStream = null;
//        BitmapRegionDecoder regionDecoder;
//        try {
//            inputStream = dataSource.getInputStream();
//            regionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
//        } finally {
//            SketchUtils.close(inputStream);
//        }

        ImageType imageType = ImageType.JPEG/*ImageType.valueOfMimeType(boundOptions.outMimeType)*/;

        return new ImageRegionDecoder(imageUri, imageSize, imageType, exifOrientation, ImageSource.create(dataSource.getInputStream(), null));
    }

    public Point getImageSize() {
        return imageSize;
    }

    public ImageType getImageType() {
        return imageType;
    }

    public String getImageUri() {
        return imageUri;
    }

    public int getExifOrientation() {
        return exifOrientation;
    }

    public boolean isReady() {
        return regionDecoder != null && !regionDecoder.isReleased();
    }

    public void recycle() {
        if (regionDecoder != null && isReady()) {
            regionDecoder.release();
            regionDecoder = null;
        }
    }

    public PixmapBuild decodeRegion(Rect srcRect, ImageSource.DecodingOptions options) {
        if (regionDecoder != null && isReady()) {
            options.desiredRegion = new ohos.media.image.common.Rect(srcRect.left, srcRect.top,
                    srcRect.right - srcRect.left, srcRect.bottom - srcRect.top);
            return new PixmapBuild(regionDecoder, options);
        } else {
            return null;
        }
    }
}
